import { App, DirectiveBinding } from "vue"

const vLazy = (observer: IntersectionObserver) => {
    return {
        // 元素在插入到DON之前调用，即：添加class，绑定图片真实地址到el上，监听el
        beforeMount: (el: HTMLImageElement, binding: DirectiveBinding) => {
            el.classList.add('op-lazyload')
            // value：传递给指令的值（在这里是图片的url）
            const { value } = binding
            el.dataset.origin = value
            observer.observe(el)
        }
    }
}

// 懒加载插件
const lazyPlugin = {
    install(app: App) {
        const observer = new IntersectionObserver(
            /**
             * IntersectionObserver的回调
             * @param entries 回调函数参数，是IntersectionObserverEntry对象数组
             * IntersectionObserverEntry的七个属性：
             * 1.boundingClientRect 目标元素的矩形信息
             * 2.intersectionRatio 相交区域和目标元素的比例值 intersectionRect/boundingClientRect 不可见时小于等于0
             * 3.intersectionRect 目标元素和视窗（根）相交的矩形信息 可以称为相交区域
             * 4.isIntersecting 目标元素当前是否可见 Boolean值 可见为true
             * 5.rootBounds 根元素的矩形信息，没有指定根元素就是当前视窗的矩形信息
             * 6.target 观察的目标元素
             * 7.time 返回一个记录从IntersectionObserver的时间到交叉被触发的时间的时间戳
             */
            (entries) => {
                entries.forEach((item) => {
                    // console.log(item, 'item')
                    if (item.isIntersecting) {
                        // 到达可视区域
                        const el = item.target as HTMLImageElement
                        // console.log(el.dataset, 'el')
                        el.src = el.dataset.origin as string
                        el.classList.remove('op-lazyload')
                        // 停止监听
                        observer.unobserve(el)
                    }
                })
            },
            {
                // 根元素设置margin-bottom:-100px，也就是滚动时交叉视图到100px,才派发事件
                rootMargin: '0px 0px -100px 0px'
            }
        )
        app.directive('lazy', vLazy(observer))
    }
}

export default lazyPlugin